#include "lwip/opt.h"
#include "lwip/mem.h"
#include "lwip/raw.h"
#include "lwip/api.h"
#include "lwip/icmp.h"
#include "lwip/netif.h"
#include "lwip/sys.h"
#include "lwip/timers.h"
#include "lwip/inet_chksum.h"
#include "lwip/sockets.h"
#include "lwip/inet.h"
#include <raw_api.h>
#include "2440lib.h"

RAW_U8  dataBuffer[100];

RAW_U32 count;

static void tcp_server_thread(void *arg)
{
	RAW_S32  length;
	RAW_S32       list_s;                /*  listening socket          */
	RAW_S32       conn_s;                /*  connection socket         */
//	short int port;                  /*  port number               */
	struct    sockaddr_in servaddr;  /*  socket address structure  */
	struct    sockaddr_in their_addr;
	unsigned int sin_size;

	if ( (list_s = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
		RAW_ASSERT(0);

	}

	 /*  Set all bytes in socket address structure to
        zero, and fill in the relevant data members   */

    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family      = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port        = htons(6333);


    /*  Bind our socket addresss to the 
	listening socket, and call listen()  */

    if (bind(list_s, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0 ) {
		RAW_ASSERT(0);
    }

    if (listen(list_s, 1) < 0 ) {
		RAW_ASSERT(0);
    }

	 sin_size = sizeof(struct sockaddr_in);
	 
	Uart_Printf("before accept\n");
	/*  Wait for a connection, then accept() it  */
	conn_s = accept(list_s, (struct sockaddr *)&their_addr, &sin_size);
	 

	Uart_Printf("after accept\n");

	
	/*  Enter an infinite loop to respond
        to client requests and echo input  */

    while ( 1 ) {

		memset(dataBuffer, 0, 100);
		
		length = recv(conn_s, dataBuffer, 20, 0);

		Uart_Printf("length received %d\n",  length);
		Uart_Printf("received string is %s\n", dataBuffer);
		Uart_Printf("received count is %d\n", count++);
		
		send(conn_s, "123456789", 10, 0);
		
		
    }


}



void tcp_server_init()
{

	sys_thread_new("ping_thread",  tcp_server_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO - 1);


}




